<?php


namespace app\live\controller;


use app\common\cachemodel\live\LiveAnchorAdmin;
use app\common\cachemodel\live\LiveAnchorInfo;
use app\common\lib\Aes;
use app\common\lib\exception\ApiException;
use app\common\model\User;
use think\Cache;
use think\Log;

class LiveAuth extends Common
{
    protected $liveInfo = null;
    protected $userInfo = null;
    protected $aid = 0;
    protected $errermsg = '';
    protected $is_simulated = false;
    protected $app_type = '';

    public function _initialize()
    {
        parent::_initialize();

        if (!$this->isLogin())
        {
            throw new ApiException($this->errermsg, 200, config('code.denied'));
        }
    }

    private function isLogin()
    {
        $LiveModel = new LiveAnchorInfo();

        if ($this->clientUserType === 'admin')
        {   // 后台
            $this->aid = $this->headers['aid'];
            $random = Cache::get('live_random:' . $this->aid, '');
            $liveId = input('live_id/d', 0);

            if (empty($this->headers['random']) || !$random || !$liveId || $random !== $this->headers['random'])
            {
                throw new ApiException('请求异常；请稍后再试～', 200, config('code.error'));
            }

            $LiveInfo = $LiveModel->getInfoById($liveId);

            if (!$LiveInfo['status'])
            {
                throw new ApiException('主播状态异常，请联系客服反馈问题～', 200, config('code.error'));
            }
            // 将 一次性 鉴权失效
            Cache::rm('live_random:' . $this->aid);
        } else
        {   // 主播端 或 APP端主播管理员
            if (isset($this->headers['app-type']))
            {
                $this->app_type = $this->headers['app-type'];
            }
            if (!isset($this->headers['access-token']) || empty($this->headers['access-token'])) throw new ApiException('前往登录', 200, 405);
            // access-token AES解密
            switch ($this->clientUserType)
            {
                case 'zhunle':
                    $accessUserToken = (new Aes())->decryptWithOpenssl($this->headers['access-token']);
                    break;
                default:
                    $accessUserToken = $this->decryptWithOpenssl($this->headers['access-token']);
            }

            if (empty($accessUserToken)) throw new ApiException('前往登录', 200, 405);

            if (!preg_match('/||/', $accessUserToken))
            {
                $this->errermsg = '您的账户登录过期，请重新登录。';
                return false;
            }

            [$token, $id] = explode('||', $accessUserToken);

            switch ($this->clientUserType)
            {
                case 'zhunle':
                    // 如果是APP 端调用
                    $id = (int)($id);
                    // 账号模拟
                    $simulation = config('app.simulation');
                    if ($id !== (int)$simulation['from'])
                    {
                        $map['id'] = $id;
                        $map['token'] = $token;
                    } else
                    {
                        $map['id'] = (int)($simulation['to'] ?: $id);
                        if ($map['id'] === $simulation['to'])
                        {   // 模拟登陆
                            $this->is_simulated = true;
                        }
                    }

                    $userinfo = (new User())->getUserinfo($map);

                    if (!$userinfo || empty($userinfo))
                    {
                        $this->errermsg = '当前账号登录过期，请您重新登录。';
                        return false;
                    }
                    if ($userinfo['forbidden'] == 1)
                    {
                        $this->errermsg = '您的账户登录过期，请重新登录。';
                        return false;
                    }
                    // 判定时间是否过期
                    if (!$this->is_simulated && time() > $userinfo['token_expire'])
                    {
                        $this->errermsg = '您的账户登录过期，请重新登录。';
                        return false;
                    }
                    // APP 端调用 APP鉴权通过
                    $this->userInfo = $userinfo;

                    // 获取当前 用户 管理的主播
                    $liveIds = (new LiveAnchorAdmin())->getAdminAnchorLiveId($userinfo['id']);

                    $liveId = input('live_id/d', 0);

//                    if (!$liveId || !in_array($liveId, $liveIds, true))
                    if (!$liveId || !in_array($liveId, $liveIds, false))
                    { // 如果管理的主播未传  或者  想要管理的主播没有管理的权限
                        throw new ApiException('请求异常；请稍后再试～', 200, config('code.error'));
                    }

                    $LiveInfo = $LiveModel->getInfoById($liveId);

                    if (!$LiveInfo['status'])
                    {
                        throw new ApiException('主播状态异常，请联系客服反馈问题～', 200, config('code.error'));
                    }
                    break;
                default:
                    // 账号模拟
                    $liveSimulation = config('live_app.simulation');
                    if (!empty($liveSimulation) && $liveSimulation['from'] && $liveSimulation['to'])
                    {//打开模拟的状态
                        if ((int)$id === (int)$liveSimulation['from'])
                        {//如果当前访问的占星师id 和配置中一样的话，那么开始模拟
                            if ($liveSimulation['to'])
                            {
                                $id = $liveSimulation['to'];
                                $this->is_simulated = true;
                            } else
                            {
                                Log::write('直播端LiveAuth模拟失败，to为空', 'error', true);
                            }
                        }
                    }
                    // 主播端 请求 验证
                    $LiveInfo = $LiveModel->getInfoById($id);

                    if (!$LiveInfo)
                    {
                        throw new ApiException('前往登录', 200, 405);
                    }
                    if (!$this->is_simulated)
                    {//不是模拟的话，判断 token 是否相同
                        if ($token !== $LiveInfo['token'])
                        {
                            $this->errermsg = '当前账号登录过期，请您重新登录。';
                            return false;
                        }
                    }

                    if (!$LiveInfo['status'])
                    {
                        $this->errermsg = '您的账户被禁用，请联系管理员。';
                        return false;
                    }

                    // 判定时间是否过期
                    if ($this->is_simulated === false && time() > $LiveInfo['token_expire'])
                    {
                        $this->errermsg = '您的账户登录过期，请重新登录。';
                        return false;
                    }
            }
        }

        $LiveInfo['id'] = (int)$LiveInfo['id'];
        $LiveInfo['live_id'] = (int)$LiveInfo['live_id'];
        $this->liveInfo = $LiveInfo;

        /**
         * 定义全局常量 UID 方便日志打印带上用户ID信息
         */
        if (!defined('USERINFO_UID'))
        {
            define('USERINFO_UID', 'liveId:' . $LiveInfo['id']);
        }

        return true;
    }

    /**
     * 获取操作用户身份信息
     * @return array
     */
    public function getUserAuth()
    { // 返回操作用户身份信息  [type=>身份类型  id=>用户身份ID]
        // $this->clientUserType 调用端类型 live=>主播端 zhunle=>APP用户端 admin=>后台
        // 身份类型  1=>admin后台管理员  2=>主播  3=>主播管理员
        // 身份信息  admin_type=>1  aid=>后台用户 aid
        // 身份信息  admin_type=>2  aid=>主播的 live_id
        // 身份信息  admin_type=>3  aid=>管理员准了APPuid
        switch ($this->clientUserType)
        {
            case 'zhunle':  // App 主播管理员
                $resData = ['admin_type' => 3, 'aid' => $this->userInfo['id']];
                break;
            case 'admin':   // 后台管理员
                $resData = ['admin_type' => 1, 'aid' => $this->aid];
                break;
            default:    // 主播
                $resData = ['admin_type' => 2, 'aid' => $this->liveInfo['live_id']];
        }

        return $resData;
    }
}
